package com.lambkit.core.loadbalance;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

/**
 * 加权轮询（WeightedRound-Robin）
 * 由于不同的服务器配置不同，因此它们处理请求的能力也不同，给配置高的机器配置相对较高的权重，
 * 让其处理更多的请求，给配置较低的机器配置较低的权重减轻期负载压力。加权轮询可以较好的解决这个问题。
 * @author yangyong
 *
 */
public class WeightRoundRobin {

	private int currentWeight;

	public void selected(int total) {
		this.currentWeight -= total;
	}

	public void incrCurrentWeight(int weight) {
		this.currentWeight += weight;
	}

	public Server selectServer(List<Server> serverList) {
		int total = 0;
		Server selectedServer = null;
		int maxWeight = 0;
		for (Server server : serverList) {
			total += server.getWeight();
			incrCurrentWeight(server.getWeight());
			// 选取当前权重最大的一个服务器
			if (selectedServer == null || maxWeight < currentWeight) {
				selectedServer = server;
				maxWeight = currentWeight;
			}
		}
		if (selectedServer == null) {
			Random random = new Random();
			int next = random.nextInt(serverList.size());
			return serverList.get(next);
		}
		selected(total);
		return selectedServer;
	}

	public static void main(String[] args) {
		List<Server> serverList = new ArrayList<>();
		serverList.add(new Server(1, "服务器1", 1));
		serverList.add(new Server(2, "服务器2", 3));
		serverList.add(new Server(3, "服务器3", 10));
		WeightRoundRobin lb = new WeightRoundRobin();
		for (int i = 0; i < 10; i++) {
			Server server = lb.selectServer(serverList);
			System.out.format("第%d次请求，选择服务器%s\n", i + 1, server.toString());
		}
	}
}
